package org.chw.callback.services;

import com.fasterxml.jackson.core.JsonProcessingException;

import java.util.Arrays;

import org.chw.callback.config.WechatConfig;
import org.chw.core.utils.ObjectMapperUtil;
import org.chw.core.utils.StringCodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @ClassName: CheckSignatureService
 * @Description: 验证消息是否来自微信服务器
 * @Author: Vincent.Chen
 * @Create: 2018/6/12 20:35
 * @Version: 1.0
 **/
@Service
public class CheckSignatureService {

  private static final Logger LOGGER = LoggerFactory.getLogger(CheckSignatureService.class);

  @Autowired
  private WechatConfig wechatConfig;

  /**
   * @Author: Vincent.Chen
   * @Description: 判读是否微信发送过来的消息
   * @Date: 2018/6/21 10:06
   * @param: [signature, timestamp]
   * @Return: boolean
   **/
  public boolean checkSignature(String signature, String timestamp, String nonce)
      throws JsonProcessingException {
    String[] strs = new String[3];
    strs[0] = this.wechatConfig.getToken();
    strs[1] = timestamp;
    strs[2] = nonce;
    LOGGER.info("字典序之前:{}", ObjectMapperUtil.getObjectMapper().writeValueAsString(strs));
    Arrays.sort(strs);
    LOGGER.info("字典序之前:{}", ObjectMapperUtil.getObjectMapper().writeValueAsString(strs));
    /*
     * Map<String, Object> map = new HashMap<String,
     * Object>(); map.put("nonce", nonce);
     * map.put("timestamp", timestamp);
     * map.put("token", this.wechatConfig.getToken());
     * List<String> list = new
     * ArrayList<String>(map.keySet()); // 进行字典序排序
     * Collections.sort(list);
     */
    StringBuilder sb = new StringBuilder();
    for (String str : strs) {
      sb.append(str);
    }
    LOGGER.info("拼接的字符串:{}", sb.toString());
    // 把按照字典序拼接好后的字符串进行sha1加密
    String mySignature = StringCodeUtils.sha1(sb.toString());
    // 加密后的字符串与微信提供的字符串对比，返回结果
    LOGGER.info("wx send signature:{},local check signature:{}", signature, mySignature);
    return signature.equals(mySignature);
  }
}
